/**
 * 
 */
package cn.edu.ustc.multicore.exercise.ch4;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * @author allewang
 *
 */
public class ALock implements Lock {
	
	ThreadLocal<Integer> mySlotIndex = new ThreadLocal<Integer> (){
		
		  protected Integer initialValue() {
		 	return 0;
		  }
		 };

		 AtomicInteger tail;
		 boolean[] flag;
		 int size;
		 
		 public ALock(int capacity){
			 size = capacity;
			 tail = new AtomicInteger(0);
			 flag = new boolean[capacity];
			 flag[0] = true;
		 }
		 
	/* (non-Javadoc)
	 * @see java.util.concurrent.locks.Lock#lock()
	 */
	public void lock() {
		int slot = tail.getAndIncrement() % size;
		mySlotIndex.set(slot);
		while (! flag[slot]) {};
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.locks.Lock#lockInterruptibly()
	 */
	public void lockInterruptibly() throws InterruptedException {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.locks.Lock#tryLock()
	 */
	public boolean tryLock() {
		// TODO Auto-generated method stub
		return false;
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.locks.Lock#tryLock(long, java.util.concurrent.TimeUnit)
	 */
	public boolean tryLock(long time, TimeUnit unit)
			throws InterruptedException {
		// TODO Auto-generated method stub
		return false;
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.locks.Lock#unlock()
	 */
	public void unlock() {
		int slot = mySlotIndex.get();
		flag[slot] = false;
		flag[(slot + 1) % size] = true;
	}

	/* (non-Javadoc)
	 * @see java.util.concurrent.locks.Lock#newCondition()
	 */
	public Condition newCondition() {
		// TODO Auto-generated method stub
		return null;
	}

}
